/*!
 Temelia - Queue samples.

 Copyright (C) 2008 Ceata (http://ceata.org/proiecte/temelia).

 @author Dascalu Laurentiu

 This program is free software; you can redistribute it and
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 3
 of the License, or (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#include "include/samples.h"
#include <temelia/queue.h>
#include <temelia/doubly_linked_list.h>

static void sample1()
{
	int i, *x, N = 2000;
	queue_t Q;

	PRINT("\n\n Sample 1 started \n\n");

	Q = queue_new(10);

	for (i = 0; i < N; i++)
	{
		x = (int *) malloc(sizeof(int));
		x[0] = i;
		queue_push_back(Q, x);
	}

	queue_iterate(Q, int_handler, NULL, 1);
	PRINT("\n");
	queue_iterate(Q, int_handler, NULL, -1);
	queue_iterate(Q, int_delete, NULL, 1);
	queue_delete(Q);

	PRINT("\n\n Sample 1 ended \n\n");
}

static void sample2()
{
	int i, *x, N = 20;
	queue_t Q;

	PRINT("\n\n Sample 2 started \n\n");

	Q = queue_new(10);

	queue_set_capacity_increment(Q, 0);

	for (i = 0; i < N; i++)
	{
		x = int_new(i);
		queue_push_front(Q, x);

		if (temelia_errno == FULL)
			free(x);
	}

	queue_iterate(Q, int_handler, NULL, 1);
	PRINT("\n");

	int_delete(queue_get_back(Q), NULL);
	queue_pop_back(Q);

	int_delete(queue_get_back(Q), NULL);
	queue_pop_back(Q);

	int_delete(queue_get_front(Q), NULL);
	queue_pop_front(Q);

	int_delete(queue_get_front(Q), NULL);
	queue_pop_front(Q);

	queue_iterate(Q, int_handler, NULL, 1);
	queue_iterate(Q, int_delete, NULL, 1);
	queue_delete(Q);

	PRINT("\n\n Sample 2 ended \n\n");
}

static void sample3()
{
	int i, *x, N = 20;
	queue_t Q;

	PRINT("\n\n Sample 3 started \n\n");

	Q = queue_new(10);
	temelia_errno = NOT_EXCEPTION;

	queue_set_capacity_increment(Q, 0);

	for (i = 0; i < N; i++)
	{
		x = (int *) malloc(sizeof(int));
		x[0] = i;
		queue_push_back(Q, x);

		if (temelia_errno == FULL)
			free(x);
	}

	PRINT("Capacity/Capacity Increment/Size %d %d %d\n",
			queue_get_capacity(Q),
			queue_get_capacity_increment(Q),
			queue_get_size(Q));

	PRINT("Front/Back");
	int_handler(queue_get_front(Q), NULL);
	int_handler(queue_get_back(Q), NULL);

	PRINT("\n%d %d\n", queue_is_empty(Q), queue_is_full(Q));

	queue_iterate(Q, int_delete, NULL, -1);

	queue_delete(Q);

	PRINT("\n\n Sample 3 ended \n\n");
}

static void sample4()
{
	queue_t Q;
	doubly_linked_list_iterator_t it;

	int i, *x, N = 20;

	PRINT("\n\n Sample 4 started \n\n");

	Q = queue_new(N / 2);

	for (i = 0; i < N; i++)
	{
		x = int_new(i);
		queue_push_back(Q, x);
	}

	PRINT("Manual iterating from begin to end\n");
	for (it = queue_get_begin(Q); it != NULL; it
			= doubly_linked_list_iterator_get_prev(it))
		PRINT("[%p, %d]\n", it,
				*(int *)doubly_linked_list_iterator_get_key(it));

	PRINT("Manual iterating from end to begin\n");
	for (it = queue_get_end(Q); it != NULL; it
			= doubly_linked_list_iterator_get_next(it))
		PRINT("[%p, %d]\n", it,
				*(int *)doubly_linked_list_iterator_get_key(it));

	queue_iterate(Q, int_delete, NULL, 1);
	queue_delete(Q);

	PRINT("\n\n Sample 4 ended \n\n");
}

void run_queue_samples()
{
	sample1();
	sample2();
	sample3();
	sample4();
}
